package com.sunyur.tailor.channel.web.outer.feishu.controller;


import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.sunyur.tailor.channel.common.middle.base.ChannelResult;
import com.sunyur.tailor.channel.common.middle.enums.MiddleResultEnum;
import com.sunyur.tailor.channel.common.middle.util.ChannelResultUtil;
import com.sunyur.tailor.channel.dal.org.entity.FSBackDO;
import com.sunyur.tailor.channel.dal.org.mapper.FSBackMapper;
import com.sunyur.tailor.channel.service.inner.workflow.param.Instance;
import com.sunyur.tailor.channel.service.inner.workflow.param.WorkFlowSyncTaskParam;
import com.sunyur.tailor.channel.service.middle.feishu.FSApprovalService;
import com.sunyur.tailor.channel.service.middle.feishu.param.AData;
import com.sunyur.tailor.channel.service.middle.feishu.param.ATaskList;
import com.sunyur.tailor.channel.service.middle.feishu.param.ApprovalByInstanceCodeDTO;
import com.sunyur.tailor.channel.service.outer.keep.service.KeepToFeishuService;
import com.sunyur.tailor.channel.web.outer.feishu.dto.FSApprovalDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


/**
 * @Author pengbing
 * @Description //飞书审批回传统一入口
 * @Date 17:10 2022/8/8
 * @Param
 * @return
 **/
@Slf4j
@RestController
@RequestMapping("/outer/FS")
public class FSApprovalController {


    @Autowired
    private FSApprovalService fsApprovalService;

    @Autowired
    private KeepToFeishuService keepToFeishuService;


    @Value("${feishu.approvalCode-url}")
    private String url;

    @Autowired
    private FSBackMapper fsBackMapper;

    private ExecutorService newSingleThreadExecutor = new ThreadPoolExecutor(10, 20, 200L,
            TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(100));




    @PostMapping(value = "/subscribe")
    public ChannelResult<Boolean> subscribe(@RequestParam("code")String approvalCode)
    {
        String authorization = keepToFeishuService.getAuthorization();
        String postUrl = url+approvalCode+"/subscribe";
        String result = HttpUtil.createPost(postUrl).header("Authorization", authorization).execute().body();
        log.info("code: {} , url: {}",approvalCode,postUrl);
        log.info("result {}",result);
        Integer code = JSON.parseObject(result).getInteger("code");
        if(code==0)
        {
            return ChannelResultUtil.success(Boolean.TRUE);
        }


        return ChannelResultUtil.success(Boolean.FALSE);
    }

    @PostMapping(value = "/Approval", produces = MediaType.APPLICATION_JSON_VALUE)
    public Map<String,Object> approval(@RequestBody FSApprovalDTO fsApprovalDTO) {

        //睡眠1秒
        try {
            log.info("睡眠开始");
            Thread.sleep(2000);
            log.info("睡眠结束");
        } catch (InterruptedException e) {
            log.error("睡眠异常",e);
        }

        log.info("FSApprovalController approval param:{}", JSON.toJSONString(fsApprovalDTO));
        Map<String,Object> map =new HashMap<>();
        map.put("challenge",fsApprovalDTO.getChallenge());
        ChannelResult<Map<String,Object>> result = new ChannelResult<>();
        result.setContent(map);

        //异步处理
        newSingleThreadExecutor.execute(() -> {

            log.info("异步开始~");
                WorkFlowSyncTaskParam workFlowSyncTaskParam = getWorkFlowSyncTaskParam(fsApprovalDTO);
                if(Objects.isNull(workFlowSyncTaskParam)){
                    log.info("异步异常结束~");
                    return;
                }

                fsApprovalService.syncTask(workFlowSyncTaskParam);


        });

        log.info("FSApprovalController approval return:{}", JSON.toJSONString(result));


        return result.getContent();


    }


    public WorkFlowSyncTaskParam getWorkFlowSyncTaskParam(FSApprovalDTO fsApprovalDTO){

        WorkFlowSyncTaskParam flowSyncTaskParam =new WorkFlowSyncTaskParam();
        Map<String,Object> event = (Map<String, Object>) fsApprovalDTO.getEvent();

        List<WorkFlowSyncTaskParam.Task> completedTasks = new ArrayList<>();

        List<WorkFlowSyncTaskParam.Task> pendingTasks = new ArrayList<>();

        if(Objects.isNull(event))
        {
            return null;
        }

//        if(!"approval_instance".equals(event.get("type")))
//        {
//            return null;
//        }
//
//        if(!event.get("status").equals("APPROVED")&&!event.get("status").equals("REJECTED")){
//            return null;
//        }

        String instanceCode = event.get("instance_code").toString();
        FSBackDO fsBackDO = fsApprovalService.getFSBackDOByInstanceCode(instanceCode);
        if(Objects.isNull(fsBackDO)|| fsBackDO.getInstanceStatus()==1)
        {
            log.error("cant find fsBackDO in db  instance_code : {}",instanceCode);
            return null;
        }
        //根据InstanceCode 查询 https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/approval-v4/instance/get

        ChannelResult approvalByInstanceCode = fsApprovalService.getApprovalByInstanceCode(instanceCode);
        if (!approvalByInstanceCode.getCode().equals(MiddleResultEnum.SUCCESS.getCode()))
        {
            return null;
        }
        //根据userId查询用户姓名

        ApprovalByInstanceCodeDTO approval  = (ApprovalByInstanceCodeDTO) approvalByInstanceCode.getContent();
        AData data = approval.getData();

        log.info("AData: {}",data);
        Instance instance = new Instance();
        instance.setName("审批");
        instance.setBusiness(fsBackDO.getWorkflowBusiness());
        instance.setAction(fsBackDO.getAction());
        instance.setBusinessCode(fsBackDO.getBusinessCode());

        if(data.getStatus().equals("PENDING"))
        {
            instance.setInstanceStatus(0); //待审批
            instance.setProcessStatus(0);
        }else if (data.getStatus().equals("APPROVED") ){

            instance.setInstanceStatus(1); //通过
            instance.setProcessStatus(1);

            fsBackDO.setInstanceStatus(1);
            fsBackMapper.updateById(fsBackDO);

        }else if (data.getStatus().equals("REJECTED"))
        {
            instance.setInstanceStatus(1); // 驳回
            instance.setProcessStatus(2);

            fsBackDO.setInstanceStatus(1);
            fsBackMapper.updateById(fsBackDO);
        }


        List<ATaskList> task_list = data.getTask_list();
        for (ATaskList aTaskList : task_list) {
            String userId = aTaskList.getUser_id();
            ChannelResult approvalNameByUserId = fsApprovalService.getApprovalNameByUserId(userId);
            if (!approvalNameByUserId.getCode().equals(MiddleResultEnum.SUCCESS.getCode()))
            {
                return null;
            }

            String name = String.valueOf(approvalNameByUserId.getContent());
            log.info("user_id: {} username： {}",userId,name);
            if(aTaskList.getStatus().equals("PENDING"))
            {
                WorkFlowSyncTaskParam.Task task =  getTask(pendingTasks, aTaskList, userId, name);
                log.info("task: {}",task);
                pendingTasks.add(task);


            }else if(aTaskList.getStatus().equals("APPROVED"))
            {
                WorkFlowSyncTaskParam.Task task = getTask(completedTasks, aTaskList, userId, name);
                log.info("task: {}",task);
                completedTasks.add(task);

            }else if(aTaskList.getStatus().equals("REJECTED"))
            {
                WorkFlowSyncTaskParam.Task task =  getTask(completedTasks, aTaskList, userId, name);
                log.info("task: {}",task);
                completedTasks.add(task);

            }else
            {
                return null;
            }

        }



        flowSyncTaskParam.setInstance(instance);


        //拼装参数
        flowSyncTaskParam.setCompletedTasks(completedTasks);
        flowSyncTaskParam.setPendingTasks(pendingTasks);

        return flowSyncTaskParam;
    }

    private WorkFlowSyncTaskParam.Task getTask(List<WorkFlowSyncTaskParam.Task> pendingTasks, ATaskList aTaskList, String userId, String name) {
        WorkFlowSyncTaskParam.Task task = new WorkFlowSyncTaskParam.Task();
        task.setTaskId(aTaskList.getNode_id());
        task.setNodeName(aTaskList.getNode_name());

        task.setApproverCode(userId);
        task.setApproverName(name);
        if (aTaskList.getStatus().equals("APPROVED"))
        {
            task.setProcessStatus(1);
        }else {
            task.setProcessStatus(2);
        }
        task.setTaskStatus(1);
        task.setProcessTime(Long.valueOf(aTaskList.getStart_time()));
        if(aTaskList.getType().equals("AND"))
        {
            task.setCountersign(1); //会签
        }else {
            task.setCountersign(2); // 或签
        }

       return task;
    }
}
